//
// Created by 吴喆 on 2020/3/25.
//

#include "BulletStateMachine.h"
#include "../../engine/Bullet.h"

BulletStateMachine::BulletStateMachine() {
    currentState = new BulletLaunchState;
}

PlayableState *BulletLaunchState::update(Playable &playable) {
    if (playable.currentAnimation->isOver) {
        return new BulletOnTheWayState;
    }
    return nullptr;
}

PlayableState *BulletLaunchState::handleInput(Playable &playable, KeyEvent *event) {
    return nullptr;
}

void BulletLaunchState::initAnimation() {
    auto *animation = new Animation(10, false);
    animation->addFrame(ResourceManager::getTexture("player.Hero - 8x_Hero - Projectile_0.png"));
    animationMap[0] = animation;
}

void BulletLaunchState::enter(Playable &playable) {
    PlayableState::enter(playable);
}

PlayableState *BulletOnTheWayState::update(Playable &playable) {
    auto bullet = dynamic_cast<Bullet *>(&playable);
    if (bullet) {
        if(glm::distance(bullet->currPosition, bullet->initPosition) >= bullet->maxRange) {
            return new BulletEndState;
        } else if (bullet->isContacted) {
            return new BulletEndState;
        }
    }
    playable.body.instance->ApplyForce(-playable.body.instance->GetMass() * playable.body.instance->GetWorld()->GetGravity(), playable.body.instance->GetWorldCenter(), true);
    return nullptr;
}

void BulletOnTheWayState::initAnimation() {
    auto *animation = new Animation(50, true);
    animation->addFrame(ResourceManager::getTexture("player.Hero - 8x_Hero - Projectile_0.png"));
    animation->addFrame(ResourceManager::getTexture("player.Hero - 8x_Hero - Projectile_1.png"));
    animation->addFrame(ResourceManager::getTexture("player.Hero - 8x_Hero - Projectile_2.png"));
    animationMap[0] = animation;
}

void BulletOnTheWayState::enter(Playable &playable) {
    PlayableState::enter(playable);
    auto bullet = dynamic_cast<Bullet *>(&playable);
    if (bullet) {
        playable.body.instance->ApplyForce(-playable.body.instance->GetMass() * playable.body.instance->GetWorld()->GetGravity(), playable.body.instance->GetWorldCenter(), true);
        playable.body.instance->SetLinearVelocity(b2Vec2(-(bullet->Playable::direction == DIRECTION::LEFT?glm::vec2(-1,0):glm::vec2(1,0)).x *  bullet->speed, bullet->direction.y *  bullet->speed));
    }

}


void BulletEndState::initAnimation() {
    auto *animation = new Animation(50, false);
    animation->addFrame(ResourceManager::getTexture("player.Hero - 8x_Explosion_0.png"));
    animation->addFrame(ResourceManager::getTexture("player.Hero - 8x_Explosion_1.png"));
    animation->addFrame(ResourceManager::getTexture("player.Hero - 8x_Explosion_2.png"));
    animation->addFrame(ResourceManager::getTexture("player.Hero - 8x_Explosion_3.png"));
    animationMap[0] = animation;
}

PlayableState *BulletEndState::update(Playable &playable) {
    if (playable.currentAnimation->isOver) {
        auto bullet = dynamic_cast<Bullet *>(&playable);
        if (bullet) {
            bullet->isOver = true;
        }
    }
    playable.body.instance->ApplyForce(-playable.body.instance->GetMass() * playable.body.instance->GetWorld()->GetGravity(), playable.body.instance->GetWorldCenter(), true);
    return nullptr;
}

void BulletEndState::enter(Playable &playable) {
    PlayableState::enter(playable);
    auto bullet = dynamic_cast<Bullet *>(&playable);
    if (bullet) {
        playable.body.instance->ApplyForce(-playable.body.instance->GetMass() * playable.body.instance->GetWorld()->GetGravity(), playable.body.instance->GetWorldCenter(), true);
        playable.body.instance->SetLinearVelocity(b2Vec2(0, 0));
    }
}
